package com.teemor.im.remoting.netty;


import com.teemor.im.common.enums.MessageTypeEnum;
import com.teemor.im.common.model.ImMessage;
import com.teemor.im.remoting.session.LocalSession;
import com.teemor.im.remoting.session.ServerSession;
import com.teemor.im.remoting.session.SessionManager;
import com.teemor.im.remoting.window.WindowManager;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * Created by 尼恩 @ 疯狂创客圈
 * <p>
 * WebSocket 帧：WebSocket 以帧的方式传输数据，每一帧代表消息的一部分。一个完整的消息可能会包含许多帧
 */
@Slf4j
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //增加消息的引用计数（保留消息），并将他写到 ChannelGroup 中所有已经连接的客户端
        ServerSession session = LocalSession.getSession(ctx);

        ImMessage message = ChatProcesser.inst().onMessage(msg.text(), session);
        if (message != null) {
            switch (message.getMsgType()) {
                case MessageTypeEnum.MSG: //发送消息
                    WindowManager.pushMessage(session, message);
                    break;
                case MessageTypeEnum.INIT:  //新建窗口
                    WindowManager.addToWindow(message.getTargetId(), session);
                    WindowManager.pullMessage(message.getTargetId(), session);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //是否握手成功，升级为 Websocket 协议
        if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
            // 握手成功，移除 HttpRequestHandler，因此将不会接收到任何消息
            // 并把握手成功的 Channel 加入到 ChannelGroup 中
            LocalSession session = new LocalSession(ctx.channel());
            SessionManager.inst().addLocalSession(session);
            String echo = ChatProcesser.inst().onOpen(session);

//          SessionMap.inst().sendMsg(ctx, echo);

        } else if (evt instanceof IdleStateEvent) {
            IdleStateEvent stateEvent = (IdleStateEvent) evt;
            if (stateEvent.state() == IdleState.READER_IDLE) {
                LocalSession session = LocalSession.getSession(ctx);
//                SessionMap.inst().remove(session);
                session.processError(null);

            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }


}
